/**
 * @file profiling_manager.h
 *
 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef ACL_PROFILING_MANAGER_H_
#define ACL_PROFILING_MANAGER_H_

#include "profiling.h"
#include <mutex>
#include <unordered_set>
#include <map>
#include "toolchain/prof_common.h"
#include "common/log_inner.h"

namespace acl {
    class AclProfilingManager final {
    public:
        static AclProfilingManager &GetInstance();
        // init acl prof module
        aclError Init();
        // uninit acl prof module
        aclError UnInit();
        // acl profiling module is running or not
        bool AclProfilingIsRun() const
        {
            return isProfiling_;
        }

        // return flag of device list that needs report prof data is empty or not
        bool IsDeviceListEmpty() const;
        aclError ProfilingData(ReporterData &data);
        aclError AddDeviceList(const uint32_t *const deviceIdList, const uint32_t deviceNums);
        aclError RemoveDeviceList(const uint32_t *const deviceIdList, const uint32_t deviceNums);
        bool IsDeviceEnable(const uint32_t &deviceId) const;

    private:
        ~AclProfilingManager();
        AclProfilingManager();
        bool isProfiling_ = false;
        std::mutex mutex_;
        std::unordered_set<uint32_t> deviceList_;
        std::map<std::string, uint64_t> HashMap = {};
    };

    class ACL_FUNC_VISIBILITY AclProfilingReporter {
    public:
        AclProfilingReporter(const char_t *const functionName, const MsprofAclApiType functionType);
        virtual ~AclProfilingReporter();
    private:
        int64_t startTime_ = 0;
        int32_t deviceId_ = -1;
        const char_t* funcTag_ = nullptr;
        const char_t* funcName_;
        const MsprofAclApiType funcType_;
    };

} // namespace acl

#define ACL_PROFILING_REG(funcType) \
    const acl::AclProfilingReporter g_##funcType##_profiling_reporter(__FUNCTION__, (funcType))

#endif // ACL_PROFILING_MANAGER_H_
